﻿#include <string.h>
#include "consoleimage.h"

ConsoleImage::ConsoleImage()
{
}

ConsoleImage::ConsoleImage(int width, int height, char value)
{
	_data.reset(new Data(width,height,value));
}

ConsoleImage::~ConsoleImage()
{
}

ConsoleImage::ConsoleImage(const ConsoleImage & other) :ConsoleImage()
{
	operator =(other);
}

ConsoleImage::ConsoleImage(ConsoleImage && other) : ConsoleImage()
{
	operator =(other);
}

ConsoleImage & ConsoleImage::operator=(const ConsoleImage& other)
{
	// TODO: �ڴ˴����� return ���
	_data.reset();
	if (other._data) {
		_data.reset(new Data(other._data->m_width, other._data->m_height, ' '));
		memcpy(_data->m_data, other._data->m_data, _data->m_height * _data->m_width);
	}

	return *this;
}

ConsoleImage & ConsoleImage::operator=(ConsoleImage && other)
{
	_data = std::move(other._data);

	return *this;
}

bool ConsoleImage::operator==(const ConsoleImage & other) const
{
	if (_data == NULL && other._data == NULL) {
		return true;
	}

	if (_data != NULL && other._data != NULL) {
		if (_data->m_height == other._data->m_height && _data->m_width == other._data->m_height) {
			if (memcmp(_data->m_data, other._data->m_data, _data->m_height * _data->m_width) == 0) {
				return true;
			}
		}
	}

	return false;
}

bool ConsoleImage::isValidate() const
{
	return (bool)_data;
}

int ConsoleImage::width() const
{
	if (_data) {
		return _data->m_width;
	}
	return -1;
}

int ConsoleImage::height() const
{
	if (_data) {
		return _data->m_height;
	}
	return -1;
}

void ConsoleImage::set(int x, int y, char value)
{
	char v[] = { value,'\0' };
	set(x, y, v);
}

void ConsoleImage::set(int x, int y, const char * value)
{
	if (isValidate()) {
		int len = strlen(value);
		if (len + x - 1 >= _data->m_width) {
			return;
		}

		int local = pos(x, y);
		if (local != -1) {
			memcpy(_data->m_data + local, value, len);
		}
	}
}

const char * ConsoleImage::data() const
{
	if (_data) {
		return _data->m_data;
	}
	return NULL;
}

int ConsoleImage::dataLen() const
{
	if (_data) {
		return _data->m_height * _data->m_width;
	}
	return -1;
}

ConsoleImage::Data::Data(int width, int height,char value)
{
	this->m_width = width;
	this->m_height = height;
	m_data = new char[height * width + 1];
	m_data[height * width + 1] = '\0';
	memset(m_data, value, m_width * m_height);
}

ConsoleImage::Data::~Data()
{
	delete m_data;
}
